/**
 * Random String Utilities
 * A comprehensive library for generating various types of random strings
 * @version 1.0.0
 * @license MIT
 */

/**
 * 随机字符串工具类
 * 提供各种随机字符串生成方法
 */
class RandomStringUtils {
    /**
     * 打乱字符串顺序
     * @param {string} str - 要打乱的字符串
     * @returns {string} 打乱后的字符串
     */
    static shuffleString(str) {
        return str.split('').sort(() => Math.random() - 0.5).join('');
    }
    
    /**
     * 生成指定长度的随机字符串，可选择包含的字符类型
     * @param {number} length - 生成的字符串长度，默认16位，范围6-128
     * @param {Object} options - 配置选项
     * @param {boolean} options.includeUppercase - 是否包含大写字母，默认true
     * @param {boolean} options.includeLowercase - 是否包含小写字母，默认true
     * @param {boolean} options.includeNumbers - 是否包含数字，默认true
     * @param {boolean} options.includeSpecialChars - 是否包含特殊符号，默认true
     * @param {string} options.customSpecialChars - 自定义特殊字符集，默认为常见特殊符号
     * @returns {string} 生成的随机字符串
     */
    static generateRandomString(length = 16, options = {}) {
        // 参数验证
        if (!Number.isInteger(length) || length < 6 || length > 128) {
            throw new Error('长度必须是6-128之间的整数');
        }

        // 默认选项
        const {
            includeUppercase = true,
            includeLowercase = true,
            includeNumbers = true,
            includeSpecialChars = true,
            customSpecialChars = '!@#$%^&*()_+-=[]{}|;:,.<>?'
        } = options;

        // 验证至少选择了一种字符类型
        if (!includeUppercase && !includeLowercase && !includeNumbers && !includeSpecialChars) {
            throw new Error('至少需要选择一种字符类型');
        }

        // 构建字符集 - 每次生成时随机排列，增加安全性
        let allChars = '';
        
        if (includeUppercase) {
            allChars += this.shuffleString('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
        }
        
        if (includeLowercase) {
            allChars += this.shuffleString('abcdefghijklmnopqrstuvwxyz');
        }
        
        if (includeNumbers) {
            allChars += this.shuffleString('0123456789');
        }
        
        if (includeSpecialChars) {
            allChars += this.shuffleString(customSpecialChars);
        }
        
        // 最终打乱所有字符
        allChars = this.shuffleString(allChars);
        
        // 根据选择的字符类型确保包含各类字符
        let result = [];
        
        // 确保至少包含每个已选字符类型中的一个字符
        if (includeUppercase) {
            const upperChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
            result.push(upperChars[Math.floor(Math.random() * upperChars.length)]);
        }
        
        if (includeLowercase) {
            const lowerChars = 'abcdefghijklmnopqrstuvwxyz';
            result.push(lowerChars[Math.floor(Math.random() * lowerChars.length)]);
        }
        
        if (includeNumbers) {
            const numChars = '0123456789';
            result.push(numChars[Math.floor(Math.random() * numChars.length)]);
        }
        
        if (includeSpecialChars) {
            result.push(customSpecialChars[Math.floor(Math.random() * customSpecialChars.length)]);
        }
        
        // 检查是否满足最小长度要求
        if (result.length > length) {
            // 如果强制包含的字符数超过了指定长度，截取前length个
            result = result.slice(0, length);
        } else {
            // 填充剩余的字符
            const remainingLength = length - result.length;
            for (let i = 0; i < remainingLength; i++) {
                result.push(allChars[Math.floor(Math.random() * allChars.length)]);
            }
        }
        
        // 打乱顺序并返回
        return result.sort(() => Math.random() - 0.5).join('');
    }

    /**
     * 生成只包含字母的随机字符串
     * @param {number} length - 生成的字符串长度，默认16位，范围6-128
     * @returns {string} 生成的随机字符串
     */
    static generateAlphabeticString(length = 16) {
        // 参数验证
        if (!Number.isInteger(length) || length < 6 || length > 128) {
            throw new Error('长度必须是6-128之间的整数');
        }

        // 字符集每次使用时随机排列
        const uppercaseChars = this.shuffleString('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
        const lowercaseChars = this.shuffleString('abcdefghijklmnopqrstuvwxyz');
        const allChars = this.shuffleString(uppercaseChars + lowercaseChars);
        
        let result = '';
        for (let i = 0; i < length; i++) {
            result += allChars[Math.floor(Math.random() * allChars.length)];
        }
        
        return result;
    }

    /**
     * 生成只包含数字的随机字符串
     * @param {number} length - 生成的字符串长度，默认16位，范围6-128
     * @returns {string} 生成的随机字符串
     */
    static generateNumericString(length = 16) {
        // 参数验证
        if (!Number.isInteger(length) || length < 6 || length > 128) {
            throw new Error('长度必须是6-128之间的整数');
        }

        // 数字字符集每次使用时随机排列
        const numberChars = this.shuffleString('0123456789');
        
        let result = '';
        for (let i = 0; i < length; i++) {
            result += numberChars[Math.floor(Math.random() * numberChars.length)];
        }
        
        return result;
    }

    /**
     * 生成包含字母和数字的随机字符串（无特殊符号）
     * @param {number} length - 生成的字符串长度，默认16位，范围6-128
     * @returns {string} 生成的随机字符串
     */
    static generateAlphanumericString(length = 16) {
        // 参数验证
        if (!Number.isInteger(length) || length < 6 || length > 128) {
            throw new Error('长度必须是6-128之间的整数');
        }

        // 字符集每次使用时随机排列
        const uppercaseChars = this.shuffleString('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
        const lowercaseChars = this.shuffleString('abcdefghijklmnopqrstuvwxyz');
        const numberChars = this.shuffleString('0123456789');
        const allChars = this.shuffleString(uppercaseChars + lowercaseChars + numberChars);
        
        let result = '';
        for (let i = 0; i < length; i++) {
            result += allChars[Math.floor(Math.random() * allChars.length)];
        }
        
        return result;
    }

    /**
     * 生成用于密钥的强随机字符串
     * @param {number} length - 密钥长度，默认16位，范围6-128
     * @returns {string} 生成的密钥字符串
     */
    static generateStrongKey(length = 16) {
        return this.generateRandomString(length);
    }
}

// 导出模块
module.exports = RandomStringUtils;